package com.zmj.sy.mom.srv.aps.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmj.sy.mom.srv.aps.bean.bo.aps.DetailPhaseMapBo;
import com.zmj.sy.mom.srv.aps.bean.entity.aps.AdoOrder;
import com.zmj.sy.mom.srv.aps.bean.entity.aps.AdoWorkDetail;
import com.zmj.sy.mom.srv.aps.bean.entity.base.BaseEntity;
import com.zmj.sy.mom.srv.aps.bean.entity.base.GroupAlternative;
import com.zmj.sy.mom.srv.aps.bean.entity.base.Message;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.JobPlanReportDiff;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.PartPallet;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.WorkRecord;
import com.zmj.sy.mom.srv.aps.bean.entity.order.*;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Group;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Phase;
import com.zmj.sy.mom.srv.aps.bean.vo.base.*;
import com.zmj.sy.mom.srv.aps.bean.vo.dayworkorder.*;
import com.zmj.sy.mom.srv.aps.bean.vo.nest.andon.SendCardMsgDto;
import com.zmj.sy.mom.srv.aps.bean.vo.plan.PlanProAreaResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plan.PlanProDetailDayResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plan.PlanProDetailResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.plan.PlanProResVo;
import com.zmj.sy.mom.srv.aps.config.ProjectConfig;
import com.zmj.sy.mom.srv.aps.feign.MomAndonFeign;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.JsonUtils;
import com.zmj.sy.mom.srv.aps.utils.MessageUtils;
import com.zmj.sy.mom.srv.aps.utils.MkBeanUtils;
import com.zmj.sy.mom.srv.aps.utils.SyExceptionUtils;
import com.zmj.sy.mom.srv.aps.utils.ado.DefaultApsDayOrderRule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@RequiredArgsConstructor
@Service
public class ApsDayOrderService {

    private final ApsDayWorkOrderMapper apsDayWorkOrderMapper;
    private final OrderMapper orderMapper;
    private final AdoOrderMapper adoOrderMapper;
    private final PhaseMapper phaseMapper;
    private final OrderBomMapper orderBomMapper;
    private final ApsWorkDetailMapper apsWorkDetailMapper;
    private final DefaultApsDayOrderRule defaultApsDayOrderRule;
    private final AdoWorkDetailMapper adoWorkDetailMapper;
    private final OrderPhaseMapper orderPhaseMapper;
    private final WorkDetailTaskMapper workDetailTaskMapper;
    private final WorkReportMapper workReportMapper;
    private final WorkRecordMapper workRecordMapper;
    private final JobPlanReportDiffMapper jobPlanReportDiffMapper;
    private final GroupMapper groupMapper;
    private final PartPalletMapper partPalletMapper;
    private final PhaseGroupMapper phaseGroupMapper;
    private final OrderPartMapper orderPartMapper;
    private final ProjectConfig projectConfig;
    private final MessageUtils messageUtils;
    private final MessageMapper messageMapper;
    private final MomAndonFeign momAndonFeign;
    private final GroupAlternativeMapper groupAlternativeMapper;


    @Transactional(readOnly = true)
    public ApsDayOrderPhaseGetResVo phaseList(ApsDayOrderPhaseGetReqVo reqVo) {

        Map<String, String> params = new HashMap<>();
        params.put("PZ", "一拼");
        params.put("ZT", "整加");
        params.put("WH", "转加");

        List<Phase> phaseList = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).isNotNull(Phase::getName).list();
        Map<String, Phase> phaseMap = phaseList.stream().collect(Collectors.toMap(Phase::getMyCode, e -> e));

        Order order = orderMapper.selectById(reqVo.getOrderId());

        ApsDayOrderPhaseGetResVo res = new ApsDayOrderPhaseGetResVo();
        res.setOrderId(order.getId());
        res.setPhaseCode(reqVo.getPhaseCode());
        String phaseName = params.get(reqVo.getPhaseCode());
        if (phaseName == null) {
            phaseName = phaseMap.getOrDefault(reqVo.getPhaseCode(), new Phase()).getName();
        }
        res.setPhaseName(phaseName);
        res.setTotalCount(order.getOrderQty());

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getOrderId, reqVo.getOrderId())
                .eq(AdoWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                .eq(reqVo.getPhaseCode().equals("QM"), AdoWorkDetail::getGroupCode, "4-2_QMGW_00")
                .like(reqVo.getPhaseCode().equals("PZ"), AdoWorkDetail::getPlmId, "%P1%")
                .orderByAsc(AdoWorkDetail::getPlanStartDateTime)
                .list();

        // 不为空则查询当前表，为空查询批次表
        if (CollUtil.isNotEmpty(workDetailList)) {

            List<ApsDayOrderPhaseGetItemResVo> items = workDetailList.stream()
                    .map(e -> {
                        ApsDayOrderPhaseGetItemResVo item = new ApsDayOrderPhaseGetItemResVo();
                        item.setTotalCount(e.getOrderCount().intValue());
                        item.setWorkDate(e.getPlanStartDateTime().toLocalDate());
                        return item;
                    })
                    .collect(Collectors.toList());

//            List<ApsDayOrderPhaseGetItemResVo> items = dayOrders.stream()
//                    .map(e -> {
//                        ApsDayOrderPhaseGetItemResVo item = new ApsDayOrderPhaseGetItemResVo();
//                        item.setTotalCount(e.getTotalCount());
//                        item.setWorkDate(e.getWorkDate());
//                        return item;
//                    })
//                    .collect(Collectors.toList());
            res.setItems(items);
        } else {
            List<Order> orderList = Arrays.asList(order);
//            long until = reqVo.getStartDate().until(reqVo.getEndDate(), ChronoUnit.DAYS);
//            List<LocalDate> allDate = Stream.iterate(reqVo.getStartDate(), s -> s.plusDays(1)).limit(until + 1).collect(Collectors.toList());

            Map<String, Integer> orderSuffixMap = new HashMap<>();
            orderSuffixMap.put("D", 1);
            orderSuffixMap.put("Y", 2);
            orderSuffixMap.put("Z", 3);
            orderSuffixMap.put("C", 4);
            orderSuffixMap.put("L", 5);
            orderSuffixMap.put("T", 6);
            orderSuffixMap.put("B", 7);

            orderList.sort(Comparator.comparing(Order::getConstructNo).thenComparing(e -> orderSuffixMap.get(e.getSuffix())));

            List<Integer> orderIdList = orderList.stream().map(BaseEntity::getId).collect(Collectors.toList());

//            Map<String, Phase> phaseMap = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).list().stream().collect(Collectors.toMap(Phase::getMyCode, Function.identity()));

            List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().in(OrderBom::getOrderId, orderIdList).list();
            Map<Integer, Map<Integer, OrderBom>> orderIdBomIdMap = orderBomList.stream().collect(Collectors.groupingBy(OrderBom::getOrderId, Collectors.toMap(OrderBom::getId, Function.identity())));

            // 焊接与整加区
            List<ApsDayOrderPhaseGetItemResVo> items = weldingArea(reqVo, orderList, orderIdList, phaseMap, orderIdBomIdMap, orderSuffixMap, orderBomList);
            res.setItems(items);

        }

        return res;
    }

    @Transactional
    public void phaseEdit(ApsDayOrderPhaseEditReqVo reqVo) {

        int sum = reqVo.getItems().stream().mapToInt(DayWorkOrderPhaseEditItemReqVo::getTotalCount).sum();
        Order o = orderMapper.selectById(reqVo.getOrderId());
        if (sum != o.getOrderQty()) {
            throw SyExceptionUtils.e("数量不一致!");
        }

        List<String> orderType = Arrays.asList("D", "Y", "Z");
        if (!orderType.contains(o.getSuffix())) {
            throw SyExceptionUtils.e("只支持顶梁、底座、掩护梁。");
        }

        Integer count = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getOrderId, reqVo.getOrderId())
                .eq(AdoWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                .count();
        List<String> phaseNoPt = Arrays.asList("PZ", "ZT", "WH");

        if (count <= 0 && phaseNoPt.contains(reqVo.getPhaseCode())) {
            throw SyExceptionUtils.e("请先修改PT工序，如果没有则为最后一道工序");
        }

        List<OrderPhase> orderPhaseList = orderPhaseMapper.lambdaQuery()
                .eq(OrderPhase::getOrderId, reqVo.getOrderId())
                .eq(OrderPhase::getPhaseCode, reqVo.getPhaseCode())
                .eq(reqVo.getPhaseCode().equals("QM"), OrderPhase::getWorkGroupNumber, "4-2_QMGW_00")
                .list();

        if (CollUtil.isNotEmpty(orderPhaseList)) {

            List<Integer> bomIdList = orderPhaseList.stream().map(OrderPhase::getBomId).distinct().collect(Collectors.toList());
            List<OrderBom> orderBomList = orderBomMapper.lambdaQuery().in(OrderBom::getId, bomIdList).list();
            if (reqVo.getPhaseCode().equals("PZ")) {
                orderBomList.removeIf(e -> !e.getPlmId().contains("P1"));
            }

            List<OrderBom> root = new ArrayList<>(orderBomList);
            List<OrderBom> all = new ArrayList<>(orderBomList);

            List<OrderBom> allBom = orderBomMapper.lambdaQuery().eq(OrderBom::getOrderId, reqVo.getOrderId()).list();
            Map<Integer, List<OrderBom>> pidMap = allBom.stream().filter(e -> e.getPid() != null).collect(Collectors.groupingBy(OrderBom::getPid));

            while (CollUtil.isNotEmpty(root)) {
                List<OrderBom> temp = new ArrayList<>();
                for (OrderBom ob : root) {
                    List<OrderBom> orderBoms = pidMap.get(ob.getId());
                    if (CollUtil.isNotEmpty(orderBoms)) {
                        temp.addAll(orderBoms);
                    }
                }
                root = temp;
                if (CollUtil.isNotEmpty(root)) {
                    all.addAll(root);
                }
            }

            if (CollUtil.isNotEmpty(all)) {
                adoWorkDetailMapper.lambdaUpdate().in(AdoWorkDetail::getBomId, all.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList())).remove();
                adoOrderMapper.lambdaUpdate().eq(AdoOrder::getOrderId, reqVo.getOrderId()).eq(AdoOrder::getPhaseCode, reqVo.getPhaseCode()).remove();
            }

        }


        List<Order> orderList = Collections.singletonList(o);
        defaultApsDayOrderRule.process(orderList, reqVo);

    }


    public List<ApsDayOrderPhaseGetItemResVo> weldingArea(ApsDayOrderPhaseGetReqVo reqVo, List<Order> orderList, List<Integer> allOrderId, Map<String, Phase> phaseMap, Map<Integer, Map<Integer, OrderBom>> orderIdBomIdMap, Map<String, Integer> orderSuffixMap, List<OrderBom> orderBomList) {
        List<ApsDayOrderPhaseGetItemResVo> res = new ArrayList<>();

        PlanProResVo resVo = new PlanProResVo();
        resVo.setName("焊接与整加区");
        LocalDate yesterday = LocalDate.now().minusDays(1);

        List<PlanProAreaResVo> area = orderList.stream()
                .map(e -> {
                    PlanProAreaResVo areaResVo = new PlanProAreaResVo();
                    areaResVo.setOrderId(e.getId());
                    areaResVo.setConstructCode(e.getConstructNo());
                    areaResVo.setProjectName(e.getMaterName().replaceAll("[一二三四五六]拼", ""));
                    areaResVo.setTotalCount(e.getOrderQty());
                    areaResVo.setSuffix(e.getSuffix());
                    return areaResVo;
                })
                .collect(Collectors.toList());

        resVo.getArea().addAll(area);
        Map<String, Integer> params = new HashMap<>();
        params.put("PZ", 1);
        params.put("WH", 2);
        params.put("ZT", 3);
        params.put("PT", 4);
        params.put("QM", 4);

        QueryWrapper<ApsWorkDetail> weldingWrapper1 = Wrappers.query();
        weldingWrapper1.in("  awd.phase_code ", "PZ");
        weldingWrapper1.eq("  awd.type ", 2);
        weldingWrapper1.like("  awd.plm_id ", "P1");
        weldingWrapper1.in(" awd.order_id ", allOrderId);
        weldingWrapper1.groupBy("  awd.order_id,  awd.phase_code, DATE_FORMAT(DATE_SUB(awd.plan_start_date_time, INTERVAL 7 HOUR), '%Y-%m-%d'), DATE_FORMAT(DATE_SUB(awd.actual_end_date_time, INTERVAL 7 HOUR), '%Y-%m-%d') ");
        List<PlanProDetailDayResVo> dayDetail1 = apsWorkDetailMapper.weldingArea1(weldingWrapper1);

        QueryWrapper<ApsWorkDetail> weldingWrapper = Wrappers.query();
        weldingWrapper.in("  awd.phase_code ", "WH", "ZT", "PT");
        weldingWrapper.eq("  awd.type ", 2);
        weldingWrapper.in(" awd.order_id ", allOrderId);
        weldingWrapper.groupBy("  awd.order_id, awd.phase_code, awo.bom_id, awo.bom_pid, DATE_FORMAT(DATE_SUB(awd.plan_start_date_time, INTERVAL 7 HOUR), '%Y-%m-%d'), DATE_FORMAT(DATE_SUB(awd.actual_end_date_time, INTERVAL 7 HOUR), '%Y-%m-%d') ");
        List<PlanProDetailDayResVo> dayDetail = apsWorkDetailMapper.weldingArea(weldingWrapper);

        Map<Integer, Order> odMap = orderList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
        List<String> sandajian = Arrays.asList("D", "Y", "Z");
        List<OrderBom> notPtBom = orderBomList.stream().filter(e -> e.getLevel() == 1 && odMap.get(e.getOrderId()) != null && sandajian.contains(odMap.get(e.getOrderId()).getSuffix())).filter(e -> !e.getWorkChain().endsWith("PT")).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(notPtBom)) {
            for (OrderBom orderBom : notPtBom) {
                String[] split = orderBom.getWorkChain().split("-");
                QueryWrapper<ApsWorkDetail> weldingWrapper2 = Wrappers.query();
                weldingWrapper2.in("  awd.phase_code ", split[split.length - 1]);
                weldingWrapper2.eq("  awd.type ", 2);
                weldingWrapper2.in(" awo.bom_id ", orderBom.getId());
                weldingWrapper2.groupBy("  awd.order_id, awd.phase_code, awo.bom_id, awo.bom_pid, DATE_FORMAT(DATE_SUB(awd.plan_start_date_time, INTERVAL 7 HOUR), '%Y-%m-%d'), DATE_FORMAT(DATE_SUB(awd.actual_end_date_time, INTERVAL 7 HOUR), '%Y-%m-%d') ");
                List<PlanProDetailDayResVo> dayDetail2 = apsWorkDetailMapper.weldingArea(weldingWrapper2);
                dayDetail.addAll(dayDetail2);
            }

        }

        String[] typeArr = {"P1", "P2", "P3" /*, "P4", "P5" */};
        Map<String, String> map = new HashMap<>();
        map.put("P1", "一拼");
        map.put("P2", "二拼");
        map.put("P3", "三拼");
        map.put("P4", "四拼");
        map.put("P5", "五拼");

        List<ApsDayOrderPhaseGetItemResVo> list = new ArrayList<>();

        if (CollUtil.isNotEmpty(dayDetail1)) {
            dayDetail.addAll(dayDetail1);
        }


        for (PlanProDetailDayResVo planProDetailDayResVo : dayDetail) {
            planProDetailDayResVo.setDate(LocalDate.parse(planProDetailDayResVo.getDateStr(), DatePattern.NORM_DATE_FORMATTER));
            if (planProDetailDayResVo.getFinishDateStr() != null) {
                planProDetailDayResVo.setFinishDate(LocalDate.parse(planProDetailDayResVo.getFinishDateStr(), DatePattern.NORM_DATE_FORMATTER));
            }
        }


        Map<Integer, Map<String, List<PlanProDetailDayResVo>>> orderIdPhaseCodeMap = dayDetail.stream().collect(Collectors.groupingBy(PlanProDetailDayResVo::getOrderId, Collectors.groupingBy(PlanProDetailDayResVo::getPhaseCode)));

        for (PlanProAreaResVo areaR : area) {

            Map<String, List<PlanProDetailDayResVo>> stringListMap = orderIdPhaseCodeMap.get(areaR.getOrderId());

            if (CollUtil.isEmpty(stringListMap)) {
                continue;
            }
            String projectName = areaR.getProjectName();
            areaR.setProjectName(projectName.replaceAll("[一二三四五六]拼", ""));

            for (Map.Entry<String, List<PlanProDetailDayResVo>> entry : stringListMap.entrySet()) {

                String phaseCode = entry.getKey();
                List<PlanProDetailDayResVo> planProDetailDayResVos = entry.getValue();

                PlanProDetailResVo r = new PlanProDetailResVo();
                r.setPhaseCode(phaseCode);
                if (r.getPhaseCode().equals("WH")) {
                    r.setPhaseName("转加");
                } else if (r.getPhaseCode().equals("PZ")) {
                    r.setPhaseName("一拼");
                } else if (r.getPhaseCode().equals("ZT")) {
                    r.setPhaseName("整加");
                } else {
                    r.setPhaseName(phaseMap.get(phaseCode).getName());
                }
                r.setTotalCount(areaR.getTotalCount());
                r.setFinishCount(0);
                r.setTodoCount(0);
                r.setPlanCount(0);
                r.setPlanRate(new BigDecimal(0));
                areaR.getWorkDetail().add(r);

                if ((projectName.contains("侧板") || projectName.contains("连杆")) && (phaseCode.equals("WH") || phaseCode.equals("PT"))) {

                    List<PlanProDetailDayResVo> phaseList = planProDetailDayResVos.stream().filter(e -> e.getPhaseCode().equals(phaseCode)).collect(Collectors.toList());
                    LocalDate startDate = phaseList.stream().min(Comparator.comparing(PlanProDetailDayResVo::getDate)).get().getDate();
                    LocalDate endDate = phaseList.stream().max(Comparator.comparing(PlanProDetailDayResVo::getDate)).get().getDate();
                    long until = startDate.until(endDate, ChronoUnit.DAYS);
                    List<LocalDate> allDay = Stream.iterate(startDate, s -> s.plusDays(1)).limit(until + 1).collect(Collectors.toList());

                    int prePlan = calcPlanJiashu(phaseList.stream().filter(e -> e.getDate().isBefore(allDay.get(0))).collect(Collectors.toList()), orderIdBomIdMap.get(areaR.getOrderId()).values().stream().filter(e -> e.getLevel().equals(2)).collect(Collectors.toList()));
                    int proPlan = calcProJiashu(phaseList.stream().filter(e -> e.getFinishDate() != null && e.getFinishDate().isBefore(allDay.get(0))).collect(Collectors.toList()), orderIdBomIdMap.get(areaR.getOrderId()).values().stream().filter(e -> e.getLevel().equals(2)).collect(Collectors.toList()));
                    for (LocalDate day : allDay) {
                        PlanProDetailDayResVo dayData = new PlanProDetailDayResVo();
                        dayData.setDate(day);

                        int sumFinishCount = calcProJiashu(phaseList.stream().filter(e -> e.getFinishDate() != null && !e.getFinishDate().isAfter(day)).collect(Collectors.toList()), orderIdBomIdMap.get(areaR.getOrderId()).values().stream().filter(e -> e.getLevel().equals(2)).collect(Collectors.toList()));
                        int sumTotalCount = calcPlanJiashu(phaseList.stream().filter(e -> !e.getDate().isAfter(day)).collect(Collectors.toList()), orderIdBomIdMap.get(areaR.getOrderId()).values().stream().filter(e -> e.getLevel().equals(2)).collect(Collectors.toList()));

                        dayData.setFinishCount(new BigDecimal(sumFinishCount - proPlan));
                        dayData.setPlanCount(new BigDecimal(sumTotalCount - prePlan));
                        prePlan = sumTotalCount;
                        proPlan = sumFinishCount;
                        dayData.setTotalPlanCount(new BigDecimal(sumTotalCount));
                        dayData.setTotalFinishCount(new BigDecimal(sumFinishCount));

                        if (dayData.getPlanCount() != null && dayData.getPlanCount().intValue() > 0) {
                            dayData.setPlanRate(dayData.getFinishCount().divide(dayData.getPlanCount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                        }

                        if (dayData.getPlanCount() != null) {
                            int ct = dayData.getPlanCount().intValue();
                            if (ct > 0 && entry.getKey().equals(reqVo.getPhaseCode())) {
                                ApsDayOrderPhaseGetItemResVo rrr = new ApsDayOrderPhaseGetItemResVo();
                                rrr.setWorkDate(day);
                                rrr.setTotalCount(dayData.getPlanCount().intValue());
                                res.add(rrr);
                            }
                        }

//                        r.getDayList().add(dayData);
                    }

                } else {
                    BigDecimal sumFinishCount = null;
                    BigDecimal sumTotalCount = null;

                    List<PlanProDetailDayResVo> phaseList = planProDetailDayResVos.stream().filter(e -> e.getPhaseCode().equals(phaseCode)).collect(Collectors.toList());
                    LocalDate startDate = phaseList.stream().min(Comparator.comparing(PlanProDetailDayResVo::getDate)).get().getDate();
                    LocalDate endDate = phaseList.stream().max(Comparator.comparing(PlanProDetailDayResVo::getDate)).get().getDate();
                    long until = startDate.until(endDate, ChronoUnit.DAYS);
                    List<LocalDate> allDay = Stream.iterate(startDate, s -> s.plusDays(1)).limit(until + 1).collect(Collectors.toList());

                    int prePlan = phaseList.stream().filter(e -> e.getDate().isBefore(allDay.get(0))).map(PlanProDetailDayResVo::getPlanCount).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
                    int proPlan = phaseList.stream().filter(e -> e.getFinishDate() != null && e.getFinishDate().isBefore(allDay.get(0))).map(PlanProDetailDayResVo::getFinishCount).reduce(BigDecimal.ZERO, BigDecimal::add).intValue();
                    for (LocalDate day : allDay) {
                        PlanProDetailDayResVo dayData = new PlanProDetailDayResVo();
                        dayData.setDate(day);

                        sumTotalCount = phaseList.stream().filter(e -> !e.getDate().isAfter(day)).map(PlanProDetailDayResVo::getPlanCount).reduce(BigDecimal.ZERO, BigDecimal::add);
                        sumFinishCount = phaseList.stream().filter(e -> e.getFinishDate() != null && !e.getFinishDate().isAfter(day)).map(PlanProDetailDayResVo::getFinishCount).reduce(BigDecimal.ZERO, BigDecimal::add);

                        dayData.setPlanCount(sumTotalCount.subtract(new BigDecimal(prePlan)));
                        dayData.setFinishCount(sumFinishCount.subtract(new BigDecimal(proPlan)));
                        prePlan = sumTotalCount.intValue();
                        proPlan = sumFinishCount.intValue();
                        dayData.setTotalPlanCount(sumTotalCount);
                        dayData.setTotalFinishCount(sumFinishCount);
                        if (dayData.getPlanCount() != null && dayData.getPlanCount().intValue() > 0) {
                            dayData.setPlanRate(dayData.getFinishCount().divide(dayData.getPlanCount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)));
                        }

//                        r.getDayList().add(dayData);
                        if (dayData.getPlanCount() != null) {
                            int ct = dayData.getPlanCount().intValue();
                            if (ct > 0 && entry.getKey().equals(reqVo.getPhaseCode())) {
                                ApsDayOrderPhaseGetItemResVo rrr = new ApsDayOrderPhaseGetItemResVo();
                                rrr.setWorkDate(day);
                                rrr.setTotalCount(dayData.getPlanCount().intValue());
                                res.add(rrr);
                            }
                        }
                    }
                }
                areaR.getWorkDetail().sort(Comparator.comparingInt(a -> params.get(a.getPhaseCode())));

                r.setPlanCount(r.getDayList().stream().reduce(0, (a, b) -> a + (b.getPlanCount() == null ? 0 : b.getPlanCount().intValue()), Integer::sum));
                r.setDaysFinishCount(r.getDayList().stream().reduce(0, (a, b) -> a + (b.getFinishCount() == null ? 0 : b.getFinishCount().intValue()), Integer::sum));
                r.setFinishCount(r.getDayList().stream().map(PlanProDetailDayResVo::getTotalFinishCount).filter(Objects::nonNull).max(BigDecimal::compareTo).orElseGet(() -> BigDecimal.ZERO).intValue());

//                Optional<PlanProDetailDayResVo> first = r.getDayList().stream().filter(e -> yesterday.equals(e.getDate())).findFirst();
//                if(first.isPresent() && first.get().getTotalPlanCount() != null && first.get().getTotalPlanCount().compareTo(BigDecimal.ZERO) > 0){
//                    r.setDelayCount(first.get().getTotalFinishCount().divide(first.get().getTotalPlanCount(), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).intValue());
//                }

                r.setTodoCount(r.getPlanCount() - r.getFinishCount());
            }


            Integer i = orderSuffixMap.get(areaR.getSuffix());
            Optional<PlanProDetailResVo> wh = areaR.getWorkDetail().stream().filter(e -> e.getPhaseCode().equals("WH")).findFirst();
            if (wh.isPresent()) {
                BigDecimal reduce = orderIdBomIdMap.get(areaR.getOrderId()).values().stream().filter(e -> e.getLevel().equals(i <= 3 ? 1 : 2)).filter(e -> e.getMaterWeight() != null).map(OrderBom::getMaterWeight).reduce(BigDecimal.ZERO, BigDecimal::add).multiply(new BigDecimal(wh.get().getPlanCount())).divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
                areaR.setPlanWeight(reduce);
            }
        }


        return res;
    }

    private int calcProJiashu(List<PlanProDetailDayResVo> beforList, List<OrderBom> orderBoms) {
        Map<Integer, List<PlanProDetailDayResVo>> bomIdMap = beforList.stream().collect(Collectors.groupingBy(PlanProDetailDayResVo::getBomId));

        Optional<BigDecimal> min = orderBoms.stream()
                .map(e -> {
                    List<PlanProDetailDayResVo> planProDetailDayResVos = bomIdMap.get(e.getId());
                    if (CollUtil.isEmpty(planProDetailDayResVos)) {
                        return new BigDecimal(0);
                    }
                    return planProDetailDayResVos.stream().filter(e1 -> e1.getFinishCount() != null).map(PlanProDetailDayResVo::getFinishCount).reduce(BigDecimal.ZERO, BigDecimal::add).divide(e.getTotalCount(), 0, RoundingMode.DOWN);
                })
                .min(BigDecimal::compareTo);
        return min.map(BigDecimal::intValue).orElse(0);

    }

    public int calcPlanJiashu(List<PlanProDetailDayResVo> beforList, List<OrderBom> orderBoms) {
        Map<Integer, List<PlanProDetailDayResVo>> bomIdMap = beforList.stream().collect(Collectors.groupingBy(PlanProDetailDayResVo::getBomId));

        Optional<BigDecimal> min = orderBoms.stream()
                .map(e -> {
                    List<PlanProDetailDayResVo> planProDetailDayResVos = bomIdMap.get(e.getId());
                    if (CollUtil.isEmpty(planProDetailDayResVos)) {
                        return new BigDecimal(0);
                    }
                    return planProDetailDayResVos.stream().filter(e1 -> e1.getPlanCount() != null).map(PlanProDetailDayResVo::getPlanCount).reduce(BigDecimal.ZERO, BigDecimal::add).divide(e.getTotalCount(), 0, RoundingMode.DOWN);
                })
                .min(BigDecimal::compareTo);
        return min.map(BigDecimal::intValue).orElse(0);

    }

    @Transactional
    public void checkAdd(ApsDayOrderCheckAddReqVo reqVo) {
        LocalDate day = reqVo.getDay();
        Integer count = jobPlanReportDiffMapper.lambdaQuery().eq(JobPlanReportDiff::getDay, day).count();

        if (count > 0) {
            throw SyExceptionUtils.e("已经生成每日报工报告，请先清理数据");
        }

        String startDate = day + " 07:00:00";
        String endDate = day.plusDays(1) + " 07:00:00";

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .ge(AdoWorkDetail::getPlanStartDateTime, startDate)
                .lt(AdoWorkDetail::getPlanStartDateTime, endDate)
                .list();

        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .ge(WorkRecord::getWorkTime, startDate)
                .lt(WorkRecord::getWorkTime, endDate)
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();

        List<Integer> workDetailIdList = workRecordList.stream().map(WorkRecord::getApsWorkDetailId).distinct().collect(Collectors.toList());

        // 通过Detail查询PhaseId
        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        wrapper.in("awd.id", workDetailIdList);
        wrapper.eq("awd.deleted", 0);
        wrapper.groupBy("awd.phase_id, awd.id");
        List<DetailPhaseMapBo> phaseMapping = apsWorkDetailMapper.findPhaseId(wrapper);
        Map<Integer, Integer> detailPhaseMap = phaseMapping.stream().collect(Collectors.toMap(DetailPhaseMapBo::getDetailId, DetailPhaseMapBo::getPhaseId));

        Map<Integer, Integer> phaseMap = workRecordList.stream().collect(Collectors.toMap(e -> detailPhaseMap.get(e.getApsWorkDetailId()), WorkRecord::getSuccessCount, Integer::sum));

        List<Integer> orderIdList = workDetailList.stream().map(AdoWorkDetail::getOrderId).distinct().collect(Collectors.toList());
        List<Order> orders = orderMapper.selectBatchIds(orderIdList);
        Map<Integer, Order> orderList = orders.stream().collect(Collectors.toMap(BaseEntity::getId, e -> e));
        List<Integer> bomIdList = workDetailList.stream().map(AdoWorkDetail::getBomPid).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<OrderBom> orderBomList = orderBomMapper.selectBatchIds(bomIdList);
        Map<Integer, OrderBom> bomMap = orderBomList.stream().collect(Collectors.toMap(BaseEntity::getId, e -> e));

        Map<Integer, Integer> phaseCountMap = workDetailList.stream().collect(Collectors.toMap(AdoWorkDetail::getPhaseId, e -> 1, Integer::sum));

        List<JobPlanReportDiff> diffList = new ArrayList<>();
        List<String> ignorePhase = Arrays.asList("YC", "JG", "HG", "FJ", "LL", "KJ");

        for (AdoWorkDetail adoWorkDetail : workDetailList) {

            if (ignorePhase.contains(adoWorkDetail.getPhaseCode())) {
                continue;
            }

            Integer total = phaseMap.getOrDefault(adoWorkDetail.getPhaseId(), 0);

            Order order = orderList.get(adoWorkDetail.getOrderId());

            JobPlanReportDiff diff = new JobPlanReportDiff();
            diff.setDay(day);
            diff.setOrderId(adoWorkDetail.getOrderId());
            diff.setBomId(adoWorkDetail.getBomId());
            diff.setPhaseId(adoWorkDetail.getPhaseId());
            diff.setConstructionCode(order.getConstructNo());
            diff.setDeptName(order.getMaterName());
//            diff.setParentName();
            diff.setPlmId(adoWorkDetail.getPlmId());
            diff.setMaterName(adoWorkDetail.getMaterName());
            diff.setPhaseCode(adoWorkDetail.getPhaseCode());
            diff.setGroupCode(adoWorkDetail.getGroupCode());
            diff.setPlanCount(adoWorkDetail.getOrderCount().intValue());
            diff.setFinishCount(total);

            Integer ct = phaseCountMap.get(diff.getPhaseId());
            if (ct > 1) {
                if (total >= diff.getPlanCount()) {
                    diff.setType(1);
                } else {
                    diff.setType(2);
                }
            } else {
                if (total > adoWorkDetail.getOrderCount().intValue()) {
                    diff.setType(3);
                } else if (total < adoWorkDetail.getOrderCount().intValue()) {
                    diff.setType(2);
                } else {
                    diff.setType(1);
                }
            }
            phaseCountMap.put(diff.getPhaseId(), ct - 1);
            phaseMap.put(diff.getPhaseId(), total - diff.getPlanCount());

            if (adoWorkDetail.getBomPid() != null) {
                OrderBom orderBom = bomMap.get(adoWorkDetail.getBomPid());
                diff.setParentName(orderBom.getMaterName());
                diff.setParentPlmId(orderBom.getPlmId());
            }

            if (diff.getType().equals(1)) {
                diff.setStatus(2);
            } else {
                diff.setStatus(1);
            }
            diffList.add(diff);
        }

//        diffList.stream().filter(e -> e.getType().equals(1)).forEach(e -> System.out.println(JsonUtils.toJsonString(e)));
//        diffList.stream().filter(e -> e.getType().equals(2)).forEach(e -> System.out.println(JsonUtils.toJsonString(e)));

        jobPlanReportDiffMapper.insertBatch(diffList);
    }

    @Transactional
    public void checkEdit(ApsDayOrderCheckEditReqVo reqVo) {

//        int i = new Random().nextInt(6);
//        if(i < 5){
//            throw SyExceptionUtils.e("这儿有异常<br/>" +
//                    "1、不能喝水 <br/>" +
//                    "2、立定跳水<br/>" +
//                    "3、前空翻");
//        }

        if (CollUtil.isEmpty(reqVo.getItems())) {
            return;
        }

        JobPlanReportDiff diff = jobPlanReportDiffMapper.selectById(reqVo.getId());
        diff.setStatus(2);
        diff.setRemark(reqVo.getRemark());
        jobPlanReportDiffMapper.updateById(diff);

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getPhaseId, diff.getPhaseId())
                .list();

        adoWorkDetailMapper.deleteBatchIds(workDetailList.stream().map(BaseEntity::getId).collect(Collectors.toList()));

        // 删除原本的AdoWorkDetail
        AdoWorkDetail adoWorkDetail = workDetailList.get(0);
        List<ApsDayOrderCheckEditItemReqVo> items = reqVo.getItems();

        // 生成新的
        List<AdoWorkDetail> newDetailList = new ArrayList<>();
        for (ApsDayOrderCheckEditItemReqVo item : items) {

            AdoWorkDetail newDetail = new AdoWorkDetail();
            MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newDetail);
            newDetail.setOrderCount(item.getPlanCount());
            newDetail.setPlanStartDateTime(LocalDateTime.of(item.getDay(), adoWorkDetail.getPlanStartDateTime().toLocalTime()));
            newDetail.setPlanEndDateTime(LocalDateTime.of(item.getDay(), adoWorkDetail.getPlanEndDateTime().toLocalTime()));
            newDetail.setAdoOrderId(null);
            newDetailList.add(newDetail);
        }
        adoWorkDetailMapper.insertBatch(newDetailList);
    }

    @Transactional(readOnly = true)
    public BasePageResVo<ApsDayOrderCheckListResVo> checkList(ApsDayOrderCheckListReqVo reqVo) {

        Page<JobPlanReportDiff> page = jobPlanReportDiffMapper.lambdaQuery()
                .eq(JobPlanReportDiff::getDay, reqVo.getDay())
                .like(StringUtils.hasText(reqVo.getConstructionCode()), JobPlanReportDiff::getConstructionCode, reqVo.getConstructionCode())
                .like(StringUtils.hasText(reqVo.getDeptName()), JobPlanReportDiff::getDeptName, reqVo.getDeptName())
                .like(StringUtils.hasText(reqVo.getParentName()), JobPlanReportDiff::getParentName, reqVo.getParentName())
                .like(StringUtils.hasText(reqVo.getParentPlmId()), JobPlanReportDiff::getParentPlmId, reqVo.getParentPlmId())
                .like(StringUtils.hasText(reqVo.getPlmId()), JobPlanReportDiff::getPlmId, reqVo.getPlmId())
                .like(StringUtils.hasText(reqVo.getMaterName()), JobPlanReportDiff::getMaterName, reqVo.getMaterName())
                .like(StringUtils.hasText(reqVo.getPhaseCode()), JobPlanReportDiff::getPhaseCode, reqVo.getPhaseCode())
                .like(StringUtils.hasText(reqVo.getGroupCode()), JobPlanReportDiff::getGroupCode, reqVo.getGroupCode())
                .eq(reqVo.getType() != null, JobPlanReportDiff::getType, reqVo.getType())
                .eq(reqVo.getStatus() != null, JobPlanReportDiff::getStatus, reqVo.getStatus())
                .like(StringUtils.hasText(reqVo.getRemark()), JobPlanReportDiff::getRemark, reqVo.getRemark())
                .page(reqVo.toPage());

        return BasePageResVo.of(page, ApsDayOrderCheckListResVo.class);
    }

    @Transactional(readOnly = true)
    public ApsDayOrderCheckGetRootResVo checkGet(BaseIdReqVo reqVo) {

        JobPlanReportDiff diff = jobPlanReportDiffMapper.selectById(reqVo.getId());

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getPhaseId, diff.getPhaseId())
                .list();

        if (CollUtil.isEmpty(workDetailList)) {
            ApsDayOrderCheckGetRootResVo resVo = new ApsDayOrderCheckGetRootResVo();
            resVo.setTotal(0);
            resVo.setData(new ArrayList<>());
            return resVo;
        }

        List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery()
                .eq(ApsWorkDetail::getPhaseId, diff.getPhaseId())
                .in(ApsWorkDetail::getOrderType, 1, 3, 4)
                .list();

        List<Integer> apsWorkDetailIdList = list.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());

        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, apsWorkDetailIdList)
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();

        Map<LocalDate, Integer> finishCount = workRecordList.stream().collect(Collectors.toMap(e -> e.getWorkTime().minusHours(7).toLocalDate(), WorkRecord::getSuccessCount, Integer::sum));

        ApsDayOrderCheckGetRootResVo root = new ApsDayOrderCheckGetRootResVo();

        workDetailList.sort(Comparator.comparing(AdoWorkDetail::getPlanStartDateTime));

        List<ApsDayOrderCheckGetResVo> item = new ArrayList<>();
        BigDecimal planTotal = BigDecimal.ZERO;
        for (AdoWorkDetail e : workDetailList) {
            ApsDayOrderCheckGetResVo r = new ApsDayOrderCheckGetResVo();
            r.setId(e.getId());
            r.setDay(e.getPlanStartDateTime().minusHours(7).toLocalDate());
            r.setPlanCount(e.getOrderCount());
            r.setFinishCount(new BigDecimal(finishCount.getOrDefault(r.getDay(), 0)));

            planTotal = planTotal.add(r.getPlanCount());
            r.setPlanTotalCount(planTotal);
            LocalDateTime localDateTime = LocalDateTime.of(r.getDay().plusDays(1), LocalTime.of(7, 0, 0));
            Integer reduce = workRecordList.stream().filter(e1 -> e1.getWorkTime().isBefore(localDateTime)).map(WorkRecord::getSuccessCount).reduce(0, Integer::sum);
            r.setFinishTotalCount(new BigDecimal(reduce));

            item.add(r);
        }

        BigDecimal reduce = workDetailList.stream().map(AdoWorkDetail::getOrderCount).reduce(BigDecimal.ZERO, BigDecimal::add);
        root.setData(item);
        root.setTotal(reduce.intValue());
        root.setRemark(diff.getRemark());
        return root;
    }

    @Transactional
    public void checkOk(BaseIdsReqVo reqVo) {
        if (CollUtil.isEmpty(reqVo.getIds())) {
            return;
        }

        List<JobPlanReportDiff> jobPlanReportDiffs = jobPlanReportDiffMapper.selectBatchIds(reqVo.getIds());
        for (JobPlanReportDiff jobPlanReportDiff : jobPlanReportDiffs) {
            jobPlanReportDiff.setStatus(2);
            jobPlanReportDiffMapper.updateById(jobPlanReportDiff);
        }
    }

    @Transactional(readOnly = true)
    public BasePageResVo<ApsDayOrderAdoListResVo> adoList(ApsDayOrderAdoListReqVo reqVo) {
        if(reqVo.getDay() == null){
            reqVo.setDay(LocalDate.now());
        }
        LocalDate startDay = reqVo.getDay();
        LocalDate endDay = reqVo.getDay();

        String startDate = startDay + " 07:00:00";
        String endDate = endDay.plusDays(1) + " 07:00:00";

        QueryWrapper<AdoWorkDetail> wp = Wrappers.query();
        wp.eq("awd.deleted", 0);
        wp.ge("awd.plan_start_date_time", startDate);
        wp.lt("awd.plan_start_date_time", endDate);
        wp.like(StringUtils.hasText(reqVo.getConstructionCode()), "o.construct_no", reqVo.getConstructionCode());
        wp.like(StringUtils.hasText(reqVo.getDeptName()), "o.mater_name", reqVo.getDeptName());
        wp.like(StringUtils.hasText(reqVo.getParentName()), "ob.mater_name", reqVo.getParentName());
        wp.like(StringUtils.hasText(reqVo.getParentPlmId()), "ob.plm_id", reqVo.getParentPlmId());
        wp.like(StringUtils.hasText(reqVo.getPlmId()), "awd.plm_id", reqVo.getPlmId());
        wp.like(StringUtils.hasText(reqVo.getMaterName()), "awd.mater_name", reqVo.getMaterName());
        wp.like(StringUtils.hasText(reqVo.getPhaseCode()), "awd.phase_code", reqVo.getPhaseCode());
        wp.like(StringUtils.hasText(reqVo.getGroupCode()), "awd.group_code", reqVo.getGroupCode());
        Page<ApsDayOrderAdoListResVo> page = adoWorkDetailMapper.findList(wp, reqVo.toPage());
        BasePageResVo<ApsDayOrderAdoListResVo> apsDayOrderAdoListResVoBasePageResVo = new BasePageResVo<>(page.getTotal(), page.getRecords());

        Map<String, List<OrderPart>> pngUrlMap = new HashMap<>();
        if (CollUtil.isNotEmpty(page.getRecords())) {
            pngUrlMap = orderPartMapper.lambdaQuery()
                    .in(OrderPart::getPlmId, page.getRecords().stream().map(ApsDayOrderAdoListResVo::getPlmId).collect(Collectors.toList()))
                    .isNotNull(OrderPart::getPngUrl)
                    .list()
                    .stream()
                    .collect(Collectors.groupingBy(OrderPart::getPlmId));
        }

        List<Integer> apsWorkDetailIdList = apsDayOrderAdoListResVoBasePageResVo.getData().stream().map(ApsDayOrderAdoListResVo::getPhaseId).distinct().collect(Collectors.toList());

        List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery().in(ApsWorkDetail::getPhaseId, apsWorkDetailIdList).list();

        Map<Integer, Integer> apsWorkDetailMap = list.stream().collect(Collectors.toMap(BaseEntity::getId, ApsWorkDetail::getPhaseId));

        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, list.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList()))
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();

        Map<LocalDate, Map<Integer, Integer>> workRecordMap = workRecordList.stream().collect(Collectors.groupingBy(e -> e.getWorkTime().minusHours(7).toLocalDate(), Collectors.toMap(e -> apsWorkDetailMap.get(e.getApsWorkDetailId()), WorkRecord::getSuccessCount, Integer::sum)));

        for (ApsDayOrderAdoListResVo datum : apsDayOrderAdoListResVoBasePageResVo.getData()) {
            List<OrderPart> orderPartList = pngUrlMap.get(datum.getPlmId());
            if (CollUtil.isNotEmpty(orderPartList)) {
                OrderPart orderPart = orderPartList.get(0);
                datum.setPartPngPath(String.format(projectConfig.getUrlPre(), datum.getPlmId(), orderPart.getPngUrl()));
            }
            datum.setDay(datum.getPlanStartDateTime().minusHours(7).toLocalDate());
            Integer orDefault = workRecordMap.getOrDefault(datum.getDay(), new HashMap<>()).getOrDefault(datum.getPhaseId(), 0);
            datum.setFinishCount(orDefault);
        }
        return apsDayOrderAdoListResVoBasePageResVo;
    }

    @Transactional(readOnly = true)
    public ApsDayOrderAdoGetResVo adoGet(ApsDayOrderAdoGetReqVo reqVo) {

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery().eq(AdoWorkDetail::getPhaseId, reqVo.getPhaseId()).list();

        ApsDayOrderAdoGetResVo resVo = new ApsDayOrderAdoGetResVo();

        List<ApsDayOrderAdoGetDataResVo> collect = workDetailList.stream()
                .map(e -> {
                    ApsDayOrderAdoGetDataResVo r = new ApsDayOrderAdoGetDataResVo();
                    r.setId(e.getId());
                    r.setDay(e.getPlanStartDateTime().minusHours(7).toLocalDate());
                    r.setPlanCount(e.getOrderCount());
                    return r;
                })
                .collect(Collectors.toList());

        BigDecimal reduce = workDetailList.stream().map(AdoWorkDetail::getOrderCount).reduce(BigDecimal.ZERO, BigDecimal::add);
        resVo.setData(collect);
        resVo.setTotal(reduce.intValue());
        return resVo;
    }

    @Transactional
    public void adoEdit(ApsDayOrderAdoEditReqVo reqVo) {

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getPhaseId, reqVo.getPhaseId())
                .list();

        adoWorkDetailMapper.deleteBatchIds(workDetailList.stream().map(BaseEntity::getId).collect(Collectors.toList()));

        // 删除原本的AdoWorkDetail
        AdoWorkDetail adoWorkDetail = workDetailList.get(0);
        List<ApsDayOrderAdoEditDataReqVo> items = reqVo.getData();

        // 生成新的
        List<AdoWorkDetail> newDetailList = new ArrayList<>();
        for (ApsDayOrderAdoEditDataReqVo item : items) {

            AdoWorkDetail newDetail = new AdoWorkDetail();
            MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newDetail);
            newDetail.setOrderCount(item.getPlanCount());
            newDetail.setPlanStartDateTime(LocalDateTime.of(item.getDay(), adoWorkDetail.getPlanStartDateTime().toLocalTime()));
            newDetail.setPlanEndDateTime(LocalDateTime.of(item.getDay(), adoWorkDetail.getPlanEndDateTime().toLocalTime()));
            newDetail.setAdoOrderId(null);
            newDetailList.add(newDetail);
        }

        adoWorkDetailMapper.insertBatch(newDetailList);
    }

    @Transactional
    public void adoEditGroup(ApsDayOrderAdoEditGroupReqVo reqVo) {
        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getPhaseId, reqVo.getPhaseId())
                .list();
        Group group = groupMapper.lambdaQuery().eq(Group::getMyCode, reqVo.getGroupCode()).one();

        for (AdoWorkDetail adoWorkDetail : workDetailList) {
            adoWorkDetail.setGroupCode(reqVo.getGroupCode());
            adoWorkDetail.setGroupId(group.getId());
            adoWorkDetailMapper.updateById(adoWorkDetail);
        }
    }

    @Transactional
    public void checkRecommend(BaseIdsReqVo reqVo) {

        if (CollUtil.isEmpty(reqVo.getIds())) {
            throw SyExceptionUtils.e("请选择要智能审核的工单");
        }
        List<JobPlanReportDiff> jobPlanReportDiffs = jobPlanReportDiffMapper.selectBatchIds(reqVo.getIds());
        List<Integer> phaseIds = jobPlanReportDiffs.stream().map(JobPlanReportDiff::getPhaseId).distinct().collect(Collectors.toList());

        String startDate = jobPlanReportDiffs.get(0).getDay() + " 07:00:00";
        String endDate = jobPlanReportDiffs.get(0).getDay().plusDays(1) + " 07:00:00";

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .ge(AdoWorkDetail::getPlanStartDateTime, startDate)
                .in(AdoWorkDetail::getPhaseId, phaseIds)
                .list();

        List<ApsWorkDetail> apsWorkDetailList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getPhaseId, phaseIds)
                .in(ApsWorkDetail::getOrderType, 1, 3, 4)
                .list();

        Map<Integer, Integer> wdIdToPhaseIdMap = apsWorkDetailList.stream().collect(Collectors.toMap(BaseEntity::getId, ApsWorkDetail::getPhaseId));

        String str = " 07:00:00";
        if (LocalTime.now().isBefore(LocalTime.of(7, 0, 0, 0))) {
            str = LocalDate.now().minusDays(1) + str;
        } else {
            str = LocalDate.now() + str;
        }

        List<Integer> apsWorkDetailIdList = apsWorkDetailList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, apsWorkDetailIdList)
                .lt(WorkRecord::getWorkTime, str)
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();
        Map<Integer, Map<LocalDate, WorkRecord>> workRecordMap = workRecordList.stream().collect(Collectors.groupingBy(e -> wdIdToPhaseIdMap.get(e.getApsWorkDetailId()), Collectors.toMap(e -> e.getWorkTime().minusHours(7).toLocalDate(), e -> e, (e1, e2) -> {
            e1.setSuccessCount(e1.getSuccessCount() + e2.getSuccessCount());
            return e1;
        })));

        Map<Integer, List<AdoWorkDetail>> workDetailMap = workDetailList.stream().collect(Collectors.groupingBy(AdoWorkDetail::getPhaseId));

        List<Integer> adoOrderIdList = workDetailList.stream().map(AdoWorkDetail::getAdoOrderId).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        List<AdoOrder> adoOrders = adoOrderMapper.selectBatchIds(adoOrderIdList);
        Map<Integer, AdoOrder> adoOrderOrderIdMap = adoOrders.stream().collect(Collectors.toMap(AdoOrder::getOrderId, e -> e, (e1, e2) -> e1.getTotalCount() > e2.getTotalCount() ? e1 : e2));


        for (JobPlanReportDiff diff : jobPlanReportDiffs) {

            if(diff.getType().equals(1)){
                continue;
            }

            Integer phaseId = diff.getPhaseId();

            Map<LocalDate, WorkRecord> dayWorkRecordMap = workRecordMap.get(phaseId);
            if(CollUtil.isEmpty(dayWorkRecordMap)){
                diff.setStatus(2);
                jobPlanReportDiffMapper.updateById(diff);
                continue;
            }
            List<LocalDate> days = new ArrayList<>(dayWorkRecordMap.keySet());
            days.sort(Comparator.comparing(e -> e));
            List<AdoWorkDetail> adoWorkDetails = workDetailMap.get(diff.getPhaseId());

            AdoWorkDetail adoWorkDetail = adoWorkDetails.get(0);

            int oldPlanTotal1 = adoWorkDetailMapper.getPlanTotal(diff.getPhaseId()).intValue();
            int oldPlanTotal = oldPlanTotal1;
            List<AdoWorkDetail> awoList = new ArrayList<>();

            long between = ChronoUnit.SECONDS.between(adoWorkDetail.getPlanStartDateTime(), adoWorkDetail.getPlanEndDateTime());

            LocalDate lastDay = null;

            for (LocalDate day : days) {
                AdoWorkDetail newAwd = new AdoWorkDetail();
                MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newAwd);
                newAwd.setOrderCount(new BigDecimal(dayWorkRecordMap.get(day).getSuccessCount()));
                if(adoWorkDetail.getPlanStartDateTime().toLocalTime().isBefore(LocalTime.of(7, 0, 0))){
                    newAwd.setPlanStartDateTime(LocalDateTime.of(day.plusDays(1),  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                } else {
                    newAwd.setPlanStartDateTime(LocalDateTime.of(day,  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                }
                newAwd.setPlanEndDateTime(newAwd.getPlanStartDateTime().plusSeconds(between));
                oldPlanTotal1 = oldPlanTotal1 - newAwd.getOrderCount().intValue();
                lastDay = day;
                awoList.add(newAwd);
            }

            if (lastDay.isBefore(LocalDate.now().minusDays(1))) {
                lastDay = LocalDate.now().minusDays(1);
//                LocalDate day = lastDay.plusDays(1);
//                AdoWorkDetail newAwd = new AdoWorkDetail();
//                MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newAwd);
//                newAwd.setOrderCount(new BigDecimal((dayWorkRecordMap.get(day) == null )? 0 : dayWorkRecordMap.get(day).getSuccessCount()));
//                newAwd.setPlanStartDateTime(LocalDateTime.of(day,  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
//                newAwd.setPlanEndDateTime(newAwd.getPlanStartDateTime().plusSeconds(between));
//                oldPlanTotal1 = oldPlanTotal1 - newAwd.getOrderCount().intValue();
//                lastDay = day;
//                awoList.add(newAwd);
            }

            if(oldPlanTotal1 > 0){
                AdoOrder adoOrder = adoOrderOrderIdMap.get(adoWorkDetail.getOrderId());
                Integer pkgCount = adoOrder.getTotalCount();
                while(oldPlanTotal1 > 0){
                    lastDay = lastDay.plusDays(1);
                    int ct = Math.min(oldPlanTotal1, pkgCount);
                    oldPlanTotal1 = oldPlanTotal1 - ct;

                    AdoWorkDetail newAwd = new AdoWorkDetail();
                    MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newAwd);
                    newAwd.setOrderCount(new BigDecimal(ct));
                    newAwd.setPlanStartDateTime(LocalDateTime.of(lastDay,  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                    newAwd.setPlanEndDateTime(newAwd.getPlanStartDateTime().plusSeconds(between));

                    awoList.add(newAwd);
                }
            }

            adoWorkDetailMapper.lambdaUpdate()
                    .eq(AdoWorkDetail::getPhaseId, phaseId)
                    .remove();

            adoWorkDetailMapper.insertBatch(awoList);

            diff.setStatus(2);
            jobPlanReportDiffMapper.updateById(diff);

            Long newPlanTotal = adoWorkDetailMapper.getPlanTotal(diff.getPhaseId());
            if (newPlanTotal.intValue() != oldPlanTotal) {
                throw SyExceptionUtils.e("数据异常!");
            }
        }

    }

    @Transactional(readOnly = true)
    public BaseListResVo<ApsDayOrderAdoPhaseListResVo> adoPhaseList(ApsDayOrderAdoPhaseListReqVo reqVo) {

        List<OrderPhase> orderPhaseList = orderPhaseMapper.lambdaQuery().eq(OrderPhase::getBomId, reqVo.getBomId()).list();
        List<Integer> phaseIdList = orderPhaseList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        if(CollUtil.isEmpty(phaseIdList)){
            return BaseListResVo.empty();
        }

        List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery().in(ApsWorkDetail::getPhaseId, phaseIdList).list();

        Map<Integer, Integer> apsWorkDetailMap = list.stream().collect(Collectors.toMap(BaseEntity::getId, ApsWorkDetail::getPhaseId));

        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, list.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList()))
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();

        Map<Integer, Integer> workRecord = workRecordList.stream().collect(Collectors.toMap(e -> apsWorkDetailMap.get(e.getApsWorkDetailId()), WorkRecord::getSuccessCount, Integer::sum));
        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery().eq(AdoWorkDetail::getBomId, reqVo.getBomId()).list();

        List<ApsDayOrderAdoPhaseListResVo> resVo = workDetailList.stream()
                .map(e -> {
                    ApsDayOrderAdoPhaseListResVo r = new ApsDayOrderAdoPhaseListResVo();
                    BeanUtils.copyProperties(e, r);
                    r.setPlanCount(e.getOrderCount().intValue());
                    r.setFinishCount(workRecord.getOrDefault(e.getPhaseId(),0));
                    r.setPlanEndDate(e.getPlanStartDateTime().toLocalDate());
                    return r;
                })
                .collect(Collectors.toMap(ApsDayOrderAdoPhaseListResVo::getPhaseSeq, e -> e, (e1, e2) -> {
                    e1.setPlanCount(e1.getPlanCount() + e2.getPlanCount());
                    e1.setFinishCount(e1.getFinishCount());
                    e1.setPlanEndDate(e1.getPlanEndDate().isBefore(e2.getPlanEndDate()) ? e2.getPlanEndDate() : e1.getPlanEndDate());
                    if(!e1.getGroupCode().contains(e2.getGroupCode())){
                        e1.setGroupCode(e1.getGroupCode() + "<br/>" + e2.getGroupCode() );
                    }
                    return e1;
                }))
                .values()
                .stream()
                .sorted(Comparator.comparing(ApsDayOrderAdoPhaseListResVo::getPhaseSeq))
                .collect(Collectors.toList());

        return new BaseListResVo<>(resVo);
    }

    @Transactional(readOnly = true)
    public BaseListResVo<ApsDayOrderAdoPalletResVo> adoPallet(ApsDayOrderAdoPalletReqVo reqVo) {
        List<PartPallet> list = partPalletMapper.lambdaQuery()
                .eq(PartPallet::getPlmId, reqVo.getPlmId())
                .eq(PartPallet::getPrePhaseCode, reqVo.getPhaseCode())
                .eq(PartPallet::getPartType, 2)
                .list();
        return BaseListResVo.of(list, ApsDayOrderAdoPalletResVo.class);
    }

    @Transactional(readOnly = true)
    public List<BaseSelectItemResVo> adoFindGroup(ApsDayOrderAdoFindGroupReqVo reqVo) {

        Group group = groupMapper.lambdaQuery().eq(Group::getMyCode, reqVo.getGroupCode()).eq(Group::getType, 2).one();
        if(group == null){
            throw SyExceptionUtils.e("不存在该工作组!");
        }

        GroupAlternative ga = groupAlternativeMapper.lambdaQuery().eq(GroupAlternative::getGroupId, group.getId()).one();

        List<GroupAlternative> list = groupAlternativeMapper.lambdaQuery().eq(GroupAlternative::getBatchId, ga.getBatchId()).list();
        list.sort(Comparator.comparing(GroupAlternative::getGroupCode));

        return list.stream()
                .map(e -> {
                    BaseSelectItemResVo item = new BaseSelectItemResVo();
                    item.setText(e.getGroupCode());
                    item.setValue(e.getGroupCode());
                    return item;
                })
                .collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    public ApsDayOrderAdoFindPlanResVo adoFindPlan(ApsDayOrderAdoFindPlanReqVo reqVo) {


        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .eq(AdoWorkDetail::getPhaseId, reqVo.getPhaseId())
                .list();

        if (CollUtil.isEmpty(workDetailList)) {
            ApsDayOrderAdoFindPlanResVo resVo = new ApsDayOrderAdoFindPlanResVo();
            resVo.setTotal(0);
            resVo.setData(new ArrayList<>());
            return resVo;
        }

        List<ApsWorkDetail> list = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getOrderType, 1, 3, 4)
                .eq(ApsWorkDetail::getPhaseId, reqVo.getPhaseId())
                .list();

        List<Integer> apsWorkDetailIdList = list.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());

        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, apsWorkDetailIdList)
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();

        Map<LocalDate, Integer> finishCount = workRecordList.stream().collect(Collectors.toMap(e -> e.getWorkTime().minusHours(7).toLocalDate(), WorkRecord::getSuccessCount, Integer::sum));

        ApsDayOrderAdoFindPlanResVo root = new ApsDayOrderAdoFindPlanResVo();

        workDetailList.sort(Comparator.comparing(AdoWorkDetail::getPlanStartDateTime));

        List<ApsDayOrderAdoFindPlanDataResVo> item = new ArrayList<>();
        BigDecimal planTotal = BigDecimal.ZERO;
        for (AdoWorkDetail e : workDetailList) {
            ApsDayOrderAdoFindPlanDataResVo r = new ApsDayOrderAdoFindPlanDataResVo();
            r.setId(e.getId());
            r.setDay(e.getPlanStartDateTime().minusHours(7).toLocalDate());
            r.setPlanCount(e.getOrderCount());
            r.setFinishCount(new BigDecimal(finishCount.getOrDefault(r.getDay(), 0)));

            planTotal = planTotal.add(r.getPlanCount());
            r.setPlanTotalCount(planTotal);
            LocalDateTime localDateTime = LocalDateTime.of(r.getDay().plusDays(1), LocalTime.of(7, 0, 0));
            Integer reduce = workRecordList.stream().filter(e1 -> e1.getWorkTime().isBefore(localDateTime)).map(WorkRecord::getSuccessCount).reduce(0, Integer::sum);
            r.setFinishTotalCount(new BigDecimal(reduce));
            r.setGroupCode(e.getGroupCode());

            item.add(r);
        }

        BigDecimal reduce = workDetailList.stream().map(AdoWorkDetail::getOrderCount).reduce(BigDecimal.ZERO, BigDecimal::add);
        root.setData(item);
        root.setTotal(reduce.intValue());
        root.setPhaseId(reqVo.getPhaseId());
        return root;
    }

    @Transactional
    public void adoBatchGroup(ApsDayOrderAdoBatchGroupReqVo reqVo) {
        Group group = groupMapper.lambdaQuery().eq(Group::getMyCode, reqVo.getGroupCode()).one();

        if(group == null){
            throw SyExceptionUtils.e("没有找到该工作组!");
        }

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery().in(AdoWorkDetail::getId, reqVo.getIds()).list();
        for (AdoWorkDetail adoWorkDetail : workDetailList) {
            adoWorkDetail.setGroupId(group.getId());
            adoWorkDetail.setGroupCode(group.getMyCode());
            adoWorkDetailMapper.updateById(adoWorkDetail);
        }
    }

    @Transactional
    public void adoEditPlan(ApsDayOrderAdoEditPlanReqVo reqVo) {

    }

    @Transactional
    public void autoCheck(LocalDate currentDay) {

        List<Group> groupList = groupMapper.lambdaQuery().eq(Group::getAutoCheck, 2).eq(Group::getType, 2).list();
        if (CollUtil.isEmpty(groupList)) {
            return;
        }

        Map<String, Group> groupMap = groupList.stream().collect(Collectors.toMap(Group::getMyCode, e -> e));
        List<JobPlanReportDiff> jobPlanReportDiffs = jobPlanReportDiffMapper.lambdaQuery().eq(JobPlanReportDiff::getDay, currentDay).in(JobPlanReportDiff::getGroupCode, groupMap.keySet()).list();
        if (CollUtil.isEmpty(jobPlanReportDiffs)) {
            return;
        }

        List<Integer> phaseIds = jobPlanReportDiffs.stream().map(JobPlanReportDiff::getPhaseId).distinct().collect(Collectors.toList());

        String startDate = jobPlanReportDiffs.get(0).getDay() + " 07:00:00";
        String endDate = jobPlanReportDiffs.get(0).getDay().plusDays(1) + " 07:00:00";

        List<AdoWorkDetail> workDetailList = adoWorkDetailMapper.lambdaQuery()
                .ge(AdoWorkDetail::getPlanStartDateTime, startDate)
                .in(AdoWorkDetail::getPhaseId, phaseIds)
                .list();

        List<ApsWorkDetail> apsWorkDetailList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getPhaseId, phaseIds)
                .in(ApsWorkDetail::getOrderType, 1, 3, 4)
                .list();

        Map<Integer, Integer> wdIdToPhaseIdMap = apsWorkDetailList.stream().collect(Collectors.toMap(BaseEntity::getId, ApsWorkDetail::getPhaseId));

        String str = " 07:00:00";
        if (LocalTime.now().isBefore(LocalTime.of(7, 0, 0, 0))) {
            str = LocalDate.now().minusDays(1) + str;
        } else {
            str = LocalDate.now() + str;
        }

        List<Integer> apsWorkDetailIdList = apsWorkDetailList.stream().map(BaseEntity::getId).distinct().collect(Collectors.toList());
        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .in(WorkRecord::getApsWorkDetailId, apsWorkDetailIdList)
                .lt(WorkRecord::getWorkTime, str)
                .eq(WorkRecord::getType, 2)
                .eq(WorkRecord::getWorkType, 2)
                .list();
        Map<Integer, Map<LocalDate, WorkRecord>> workRecordMap = workRecordList.stream().collect(Collectors.groupingBy(e -> wdIdToPhaseIdMap.get(e.getApsWorkDetailId()), Collectors.toMap(e -> e.getWorkTime().minusHours(7).toLocalDate(), e -> e, (e1, e2) -> {
            e1.setSuccessCount(e1.getSuccessCount() + e2.getSuccessCount());
            return e1;
        })));

        Map<Integer, List<AdoWorkDetail>> workDetailMap = workDetailList.stream().collect(Collectors.groupingBy(AdoWorkDetail::getPhaseId));

        List<Integer> adoOrderIdList = workDetailList.stream().map(AdoWorkDetail::getAdoOrderId).filter(Objects::nonNull).distinct().collect(Collectors.toList());

        List<AdoOrder> adoOrders = adoOrderMapper.selectBatchIds(adoOrderIdList);
        Map<Integer, AdoOrder> adoOrderOrderIdMap = adoOrders.stream().collect(Collectors.toMap(AdoOrder::getOrderId, e -> e, (e1, e2) -> e1.getTotalCount() > e2.getTotalCount() ? e1 : e2));

        Map<String, List<JobPlanReportDiff>> params = new HashMap<>();

        for (JobPlanReportDiff diff : jobPlanReportDiffs) {

            if(diff.getType().equals(1)){
                continue;
            }
            List<JobPlanReportDiff> jobPlanReportDiffs1 = params.computeIfAbsent(diff.getGroupCode(), k -> new ArrayList<>());
            jobPlanReportDiffs1.add(diff);


            Integer phaseId = diff.getPhaseId();

            Map<LocalDate, WorkRecord> dayWorkRecordMap = workRecordMap.get(phaseId);
            if(CollUtil.isEmpty(dayWorkRecordMap)){
                diff.setStatus(2);
                jobPlanReportDiffMapper.updateById(diff);
                continue;
            }
            List<LocalDate> days = new ArrayList<>(dayWorkRecordMap.keySet());
            days.sort(Comparator.comparing(e -> e));
            List<AdoWorkDetail> adoWorkDetails = workDetailMap.get(diff.getPhaseId());

            AdoWorkDetail adoWorkDetail = adoWorkDetails.get(0);

            int oldPlanTotal1 = adoWorkDetailMapper.getPlanTotal(diff.getPhaseId()).intValue();
            int oldPlanTotal = oldPlanTotal1;
            List<AdoWorkDetail> awoList = new ArrayList<>();

            long between = ChronoUnit.SECONDS.between(adoWorkDetail.getPlanStartDateTime(), adoWorkDetail.getPlanEndDateTime());

            LocalDate lastDay = null;

            if (CollUtil.isEmpty(days)) {
                continue;
            }

            for (LocalDate day : days) {
                AdoWorkDetail newAwd = new AdoWorkDetail();
                MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newAwd);
                newAwd.setOrderCount(new BigDecimal(dayWorkRecordMap.get(day).getSuccessCount()));
                if(adoWorkDetail.getPlanStartDateTime().toLocalTime().isBefore(LocalTime.of(7, 0, 0))){
                    newAwd.setPlanStartDateTime(LocalDateTime.of(day.plusDays(1),  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                } else {
                    newAwd.setPlanStartDateTime(LocalDateTime.of(day,  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                }
                newAwd.setPlanEndDateTime(newAwd.getPlanStartDateTime().plusSeconds(between));
                oldPlanTotal1 = oldPlanTotal1 - newAwd.getOrderCount().intValue();
                lastDay = day;
                awoList.add(newAwd);
            }

            if (lastDay != null && lastDay.isBefore(LocalDate.now().minusDays(1))) {
                lastDay = LocalDate.now().minusDays(1);
            }

            if(oldPlanTotal1 > 0){
                AdoOrder adoOrder = adoOrderOrderIdMap.get(adoWorkDetail.getOrderId());
                Integer pkgCount = adoOrder.getTotalCount();
                while(oldPlanTotal1 > 0){
                    lastDay = lastDay.plusDays(1);
                    int ct = Math.min(oldPlanTotal1, pkgCount);
                    oldPlanTotal1 = oldPlanTotal1 - ct;

                    AdoWorkDetail newAwd = new AdoWorkDetail();
                    MkBeanUtils.copyPropertiesIgnore(adoWorkDetail, newAwd);
                    newAwd.setOrderCount(new BigDecimal(ct));
                    newAwd.setPlanStartDateTime(LocalDateTime.of(lastDay,  adoWorkDetail.getPlanStartDateTime().toLocalTime()));
                    newAwd.setPlanEndDateTime(newAwd.getPlanStartDateTime().plusSeconds(between));

                    awoList.add(newAwd);
                }
            }

            adoWorkDetailMapper.lambdaUpdate()
                    .eq(AdoWorkDetail::getPhaseId, phaseId)
                    .remove();

            adoWorkDetailMapper.insertBatch(awoList);

            diff.setStatus(2);
            jobPlanReportDiffMapper.updateById(diff);

            Long newPlanTotal = adoWorkDetailMapper.getPlanTotal(diff.getPhaseId());
            if (newPlanTotal.intValue() != oldPlanTotal) {
                throw SyExceptionUtils.e("数据异常!");
            }
        }

        // 保存每个工作组的数据
        for (Map.Entry<String, List<JobPlanReportDiff>> entry : params.entrySet()) {
            Group group = groupMap.get(entry.getKey());

            if(StringUtils.hasText(group.getAutoCheckUser())){
                String[] split = group.getAutoCheckUser().split(",");
                for (String usercode : split) {
                    // 发送到飞书消息，发送URL
                    String title = "APS-日计划审核 " + currentDay ;
                    String content = "日期【" + currentDay + "】工作组【" + group.getName().trim() + "】的审核报告";
                    SendCardMsgDto dto = new SendCardMsgDto();
                    dto.setReceive_id(usercode);
                    dto.setTitle(title);
                    dto.setContent(content);
                    dto.setTemplate_type("1");
                    try {
                        log.info("发送到飞书的消息：{}", JsonUtils.toJsonString(dto));
                        Result result = momAndonFeign.sendCardMsg(dto);
                        log.info("接收到飞书的消息：{}", JsonUtils.toJsonString(result));
                    } catch (Exception e){
                        log.error(e.getMessage(), e);
                    }

                    String url = "/apsSystem/taskManage/dayPlanAdjust?groupCode=" + group.getMyCode() + "&day=" + currentDay;
                    Message message = messageUtils.userBuild(usercode, title, content, content, "http", url);
                    messageMapper.insert(message);

                }
            }
        }



    }
}
